﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Elsa.Common;
using Elsa.Expressions.Contracts;
using Elsa.Extensions;
using Elsa.JavaScript.Activities;
using Elsa.JavaScript.Models;
using Elsa.Workflows;
using Elsa.Workflows.Activities.Flowchart.Models;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Memory;
using Elsa.Workflows.Models;
using Elsa.Workflows.State;
using Elsa.Workflows.UIHints;
using Microsoft.CodeAnalysis.Scripting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using T.FAS.Runtime.Base.Entity;
using T.FAS.Runtime.MF.Activities.Extensions;
using T.FAS.Runtime.MF.Dao;
using T.FAS.Runtime.MF.Entity;
using T.FAS.Runtime.MF.SPI;
using static System.Runtime.InteropServices.JavaScript.JSType;
using ElsaExpression = Elsa.Expressions.Models.Expression;
namespace T.FAS.Runtime.MF.Activities
{
    public class JavaScriptActivity : FASCodeActivity<object?>
    {
        /// <summary>
        /// The script to run.
        /// </summary>
        [Input(
            Description = "The script to run.",
            DefaultSyntax = "JavaScript",
            UIHint = InputUIHints.CodeEditor
        // UIHandler = typeof(RunJavaScriptOptionsProvider)
        )]
        public string Script { get; set; } = new("");

        [Input(Description = "参数列表", UIHint = "switch-editor", Order = 3)]
        public IList<BranchCondition> ParamList { get; set; }
        /// <summary>
        /// 节点默认输出的变量
        /// </summary>
        [Input(Description = "返回值列表", UIHint = "switch-editor", Order = 3)]
        public Dictionary<string, Variable> OutputVariables { get; set; }

      
        /// <summary>
        /// 节点默认输出的变量
        /// </summary>
        public override List<Variable> ActivityOutputVariables { get { return OutputVariables != null ? OutputVariables.Values.ToList() : new List<Variable>(); } }
       

        protected override async void Execute(ActivityExecutionContext context)
        {
            try
            {
                var outputInstanceValues = new Dictionary<string, object>();
                var v = context.GetVariableValues();
                var expressionEvaluator = context.GetRequiredService<IExpressionEvaluator>();
                var paramList = new Dictionary<string, object>();
                var inputInstanceValues = new Dictionary<string, object>();
                foreach (var param in ParamList ?? new List<BranchCondition>())
                {
                    var paramValue = await expressionEvaluator.EvaluateAsync<object?>(param.Condition, context.ExpressionExecutionContext);
                    paramList.Add(param.Label, paramValue);

                    //修改入参的值
                    inputInstanceValues[param.Label] = paramValue;
                }
                this.InputInstanceValues[context.Id] = inputInstanceValues;
                LogUtil.Log($"当前参数值：{JsonConvert.SerializeObject(paramList)}");
                var scriptBuilder = new StringBuilder();
               // var script = context.Get(Script);
                scriptBuilder.AppendLine(Script);
                scriptBuilder.AppendLine($"main({JsonConvert.SerializeObject(paramList)})");

                LogUtil.Log($"当前节点{this.Name},节点类型{this.GetType().ToString()},当前执行的脚本：{scriptBuilder.ToString()}");
                LogUtil.Log($"当前变量值：{JsonConvert.SerializeObject(v)}");
                var result = await expressionEvaluator.EvaluateAsync<object?>(JavaScriptExpression.Create(scriptBuilder.ToString()), context.ExpressionExecutionContext);
                if (OutputVariables != null && OutputVariables.Count() > 0)
                {
                    var obj = JObject.Parse(JsonConvert.SerializeObject(result));
                   
                    LogUtil.Log($"当前脚本执行结果：{JsonConvert.SerializeObject(result)}");
                    LogUtil.Log($"当前OutputVariables：{JsonConvert.SerializeObject(OutputVariables)}");
                    LogUtil.Log($"当前obj：{JsonConvert.SerializeObject(obj)}");
                    foreach (var variableName in OutputVariables.Keys)
                    {
                        if (obj.ContainsKey(variableName))
                        {
                            var variableJsonValue = obj[variableName];
                            LogUtil.Log($"当前variableJsonValue={variableJsonValue.Type}");
                            var variableValue = JArrayExtensions.ConvertJToken(variableJsonValue);
                            LogUtil.Log($"当前variableJsonValue={variableJsonValue.GetType()}");
                            LogUtil.Log($"当前variableName={variableName}：variableValue={JsonConvert.SerializeObject(variableValue)}");
                            LogUtil.Log($"当前variableName={OutputVariables[variableName].Name}：variableValue={variableValue}");


                            //向变量赋值,每次迭代运行后，都赋值为最后一次迭代运行的值
                            context.SetVariable(OutputVariables[variableName].Name, variableValue);

                            //向迭代返回值数组中赋值,这里会累计每次迭代的执行结果，返回到数组中
                            context.SetIterationVariableValue(OutputVariables[variableName].Name, variableValue);
                            v = context.GetVariableValues();
                            LogUtil.Log($"当前变量值（执行完赋值后）：{JsonConvert.SerializeObject(v)}");

                            outputInstanceValues.Add(variableName, variableValue);
                        }
                    }
                    this.OutputInstanceValues[context.Id] = outputInstanceValues;
                }

                context.SetResult(result);
            }
            catch (Exception ex)
            {
                await context.FaultAndComplete(ex, this);
            }
        }
    }
}
